package com.dadibadi.core.security;

import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

/**
 * SpringSecurity配置类
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {
    @Resource
    private TokenAuthenticationFilter tokenAuthenticationFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))

                .httpBasic(Customizer.withDefaults())
                .formLogin(AbstractHttpConfigurer::disable)
                .logout(AbstractHttpConfigurer::disable)
                .sessionManagement((sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests((authorizeRequests) ->
                        authorizeRequests
                                .requestMatchers(
                                        "/auth/api-user-account-get",
                                        "/auth/api-user-account-save",
                                        "/work/api-work-info-get",
                                        "/work/api-work-info-user",
                                        "/work/api-work-info-search",
                                        "/v3/api-docs",
                                        "/api/admin-sys-role-save",
                                        "/auth/api-user-account-register",
                                        "/api/api-file-uploader-test"

                                ).permitAll()
                                .requestMatchers(
                                        "/work/api-work-info-save",
                                        "/work/api-work-info-delete"
                                ).hasAnyRole("MEMBER","ADMIN")
                                .requestMatchers(
                                        "/user/api-user-info-delete",
                                        "/api/admin-member-apply-permit",
                                        "/api/admin-member-apply-page",
                                        "/api/admin-member-apply-list",
                                        "/admin/api-admin-work-delete"
                                ).hasAnyRole("ADMIN")
                                .anyRequest().authenticated()
                )
                .addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .csrf(AbstractHttpConfigurer::disable)
                .cors(cors -> cors.configurationSource(customCors()));


        return http.build();
    }

    CorsConfigurationSource customCors() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("*"));
        //configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS"));
        configuration.setAllowedMethods(List.of("*"));
        configuration.setAllowedHeaders(List.of("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}


